#include <stdlib.h>
#include <stdio.h>

#include "ifile.h"
#include "automate.h"
#include "listeTrans.h"
#include "liste.h"

void print_file( ifile_s *file ){
	iliste_s *liste = file->debut;
	while( liste != NULL ){
		print_iliste( liste );
		liste = liste->suiv;
	}
}

void calculeNouveauxEtats(ifile_s* filon, automate_s* automaton, iliste_s* iliston, liste_trans_s** listeTrans){
	int i, j;
	liste_s* tmp = NULL, *tmp1 = NULL;
	iliste_s* ilistonArrivee = NULL;

	for (i=0; i<automaton->sizealpha; i++){
		for (j=0; j<iliston->tailleVal; j++){
			tmp1 = automaton->trans[iliston->val[j]][i];
			while(tmp1 != NULL){
				ajouteListe(&tmp, tmp1->state);
				tmp1 = tmp1->suiv;
			}
		}

		if (tmp != NULL){
			ilistonArrivee = isListIntoIFile(filon, tmp);
			if ( ilistonArrivee == NULL ){
				ajouteIFile(filon, conversionOfListIntoIList(tmp));
				addTransIntoList(creerTransition(iliston->state, filon->fin->state, i+'a'), listeTrans);
				calculeNouveauxEtats(filon, automaton, filon->fin, listeTrans);
			}else{
				addTransIntoList(creerTransition(iliston->state, ilistonArrivee->state, i+'a'), listeTrans);
			}
		}
		libere_liste(&tmp);
	}

}

void ajouteIFile(ifile_s* filon, iliste_s* liston){
	liston->state = filon->fin->state+1; //determine le numero de letat
	filon->fin->suiv = liston;//ajout liston a la fin de la liste
	filon->fin = liston;//dernier element de la file est le dernier element de la liste
}

void libereFile( ifile_s **file ){
	libere_iliste( &(*file)->debut );
	free( *file );
	*file = NULL;
}

iliste_s* isListIntoIFile(ifile_s* filon, liste_s* liston){
	iliste_s* tmp = filon->debut;
	while( tmp != NULL){
		if ( compareListIList( tmp, liston ) ){
			return tmp;
		}
		tmp = tmp->suiv;
	}
	return NULL;
}

void initialiseIFileDepart( ifile_s *file, const int etat ){
	file->debut = (iliste_s*) malloc( sizeof( iliste_s ));
	if (file->debut == NULL){
	  fprintf(stderr, "Erreur lors d'allocation memoire\n");
	  exit(EXIT_FAILURE);
	}

	iliste_s* tmp = file->debut;
	tmp->val = malloc( sizeof( int ));
	if (tmp->val == NULL){
	  fprintf(stderr, "Erreur lors d'allocation memoire\n");
	  exit(EXIT_FAILURE);
	}
	
	tmp->tailleVal = 1;
	tmp->val[0] = etat;
	tmp->suiv = NULL;
	tmp->state = 0;

	file->fin = file->debut;
}

ifile_s* creerIFile( void ){
	ifile_s *ifile = (ifile_s*) malloc( sizeof(ifile_s) );
	if (ifile == NULL){
	  fprintf(stderr, "Erreur lors d'allocation memoire\n");
	  exit(EXIT_FAILURE);
	}
	
	ifile->debut = NULL;
	ifile->fin = NULL;

	return ifile;
}